import java.io.*;
import java.lang.Class;
import java.lang.reflect.*;

public class GenStub {

	private Class c = null;
	private File stub = null;

	public static void main(String[] args) {
		try {
			new GenStub(args[0]);
		} catch(Exception exc) {
			System.err.println("GenStub <class>");
		}
	}

	public GenStub(String s) {
		try {
			c = Class.forName(s);
			stub = new File(c.getName() + "_stub.java");
			//stub.deleteOnExit();
			if(!stub.exists()) {
				if(!stub.createNewFile()) {
					System.err.println("Problem to create the file " + stub + ".\nThe program will exit.");
					System.exit(-1);
				}
			}

			FileOutputStream fos = new FileOutputStream(stub);
			PrintStream ps = new PrintStream(fos);
			ps.println(modifier(c.getModifiers()) + " class " + c.getName() + "_stub extends SharedObject implements " +c.getName() + "_itf, java.io.Serializable {\n");

			Method[] methods = c.getDeclaredMethods();
			for(int i = 0 ; i < methods.length ; i++) {
				ps.print("\t" + modifier(methods[i].getModifiers()) + " " + methods[i].getReturnType().getName() + " " + methods[i].getName() + "(");
				Class parameters[] = methods[i].getParameterTypes();
				if(parameters.length >= 1) {
					ps.print(parameters[i].getName() + " parameter1");
				}
				for(int j = 1 ; j < parameters.length ; j++) {
					ps.print(", " + parameters[i].getName() + " parameter" + i);
				}
			       	ps.println(") {");
				ps.println("\t\t" + c.getName() + " s = (" + c.getName() + ")obj;");
				ps.print("\t\t");
				if(!methods[i].getReturnType().getName().equals("void")) {
					ps.print("return ");
				}
				ps.print("s." + methods[i].getName() + "(");
				if(parameters.length >= 1) {
					ps.print("parameter1");
				}
				for(int j = 1 ; j < parameters.length ; j++) {
					ps.print(", parameter" + i);
				}
				ps.println(");");
				ps.println("\t}\n");
			}

			ps.println("}");

		} catch(Exception exc) {
			exc.printStackTrace();
		}
	}

	public File genStub() {
		return this.stub;
	}

	public String modifier(int m) {
		switch(m) {
			case Modifier.ABSTRACT:
			       return "abstract";
			case Modifier.FINAL:
			       return "final";
			case Modifier.INTERFACE:
			       return "interface";
			case Modifier.NATIVE:
			       return "native";
			case Modifier.PRIVATE:
			       return "private";
			case Modifier.PROTECTED:
			       return "protected";
			case Modifier.PUBLIC:
			       return "public";
			case Modifier.STATIC:
			       return "static";
			case Modifier.STRICT:
			       return "strict";
			case Modifier.SYNCHRONIZED:
			       return "synchronized";
			case Modifier.TRANSIENT:
			       return "transient";
			case Modifier.VOLATILE:
			       return "volatile";
			default:
			       return "";
		}	       

	}

}
